#include "ostree-async-progress.h"
+#include "libglnx.h"
+
/**
* SECTION:ostree-async-progress
* @title: Progress notification system for asynchronous operations
* operation.
*/
-#if GLIB_SIZEOF_VOID_P == 8
-#define _OSTREE_HAVE_LP64 1
-#else
-#define _OSTREE_HAVE_LP64 0
-#endif
-
enum {
CHANGED,
LAST_SIGNAL
GMutex lock;
GMainContext *maincontext;
GSource *idle_source;
- GHashTable *uint_values;
- GHashTable *uint64_values;
+ GHashTable *values; /* (element-type uint GVariant) */
gboolean dead;
g_mutex_clear (&self->lock);
g_clear_pointer (&self->maincontext, g_main_context_unref);
g_clear_pointer (&self->idle_source, g_source_unref);
- g_hash_table_unref (self->uint_values);
- g_hash_table_unref (self->uint64_values);
+ g_hash_table_unref (self->values);
g_free (self->status);
G_OBJECT_CLASS (ostree_async_progress_parent_class)->finalize (object);
{
g_mutex_init (&self->lock);
self->maincontext = g_main_context_ref_thread_default ();
- self->uint_values = g_hash_table_new (NULL, NULL);
-#if _OSTREE_HAVE_LP64
- self->uint64_values = g_hash_table_new (NULL, NULL);
-#else
- self->uint64_values = g_hash_table_new_full (NULL, NULL,
- NULL, g_free);
-#endif
+ self->values = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_variant_unref);
}
-guint
-ostree_async_progress_get_uint (OstreeAsyncProgress *self,
- const char *key)
+/**
+ * ostree_async_progress_get_variant:
+ * @self: an #OstreeAsyncProgress
+ * @key: a key to look up
+ *
+ * Look up a key in the #OstreeAsyncProgress and return the #GVariant associated
+ * with it. The lookup is thread-safe.
+ *
+ * Returns: (transfer full) (nullable): value for the given @key, or %NULL if
+ * it was not set
+ * Since: 2017.6
+ */
+GVariant *
+ostree_async_progress_get_variant (OstreeAsyncProgress *self,
+ const char *key)
{
- guint rval;
+ GVariant *rval;
+
+ g_return_val_if_fail (OSTREE_IS_ASYNC_PROGRESS (self), NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
g_mutex_lock (&self->lock);
- rval = GPOINTER_TO_UINT (g_hash_table_lookup (self->uint_values,
- GUINT_TO_POINTER (g_quark_from_string (key))));
+ rval = g_hash_table_lookup (self->values, GUINT_TO_POINTER (g_quark_from_string (key)));
+ if (rval != NULL)
+ g_variant_ref (rval);
g_mutex_unlock (&self->lock);
+
return rval;
}
+guint
+ostree_async_progress_get_uint (OstreeAsyncProgress *self,
+ const char *key)
+{
+ g_autoptr(GVariant) rval = ostree_async_progress_get_variant (self, key);
+ return (rval != NULL) ? g_variant_get_uint32 (rval) : 0;
+}
+
guint64
ostree_async_progress_get_uint64 (OstreeAsyncProgress *self,
const char *key)
{
-#if _OSTREE_HAVE_LP64
- guint64 rval;
- g_mutex_lock (&self->lock);
- rval = (guint64) g_hash_table_lookup (self->uint64_values, GUINT_TO_POINTER (g_quark_from_string (key)));
- g_mutex_unlock (&self->lock);
- return rval;
-#else
- guint64 *rval;
- g_mutex_lock (&self->lock);
- rval = g_hash_table_lookup (self->uint64_values, (gpointer)g_quark_from_string (key));
- g_mutex_unlock (&self->lock);
- if (rval)
- return *rval;
- return 0;
-#endif
+ g_autoptr(GVariant) rval = ostree_async_progress_get_variant (self, key);
+ return (rval != NULL) ? g_variant_get_uint64 (rval) : 0;
}
static gboolean
return ret;
}
-static void
-update_key (OstreeAsyncProgress *self,
- GHashTable *hash,
- const char *key,
- gpointer value)
+/**
+ * ostree_async_progress_set_variant:
+ * @self: an #OstreeAsyncProgress
+ * @key: a key to set
+ * @value: the value to assign to @key
+ *
+ * Assign a new @value to the given @key, replacing any existing value. The
+ * operation is thread-safe. @value may be a floating reference;
+ * g_variant_ref_sink() will be called on it.
+ *
+ * Any watchers of the #OstreeAsyncProgress will be notified of the change if
+ * @value differs from the existing value for @key.
+ *
+ * Since: 2017.6
+ */
+void
+ostree_async_progress_set_variant (OstreeAsyncProgress *self,
+ const char *key,
+ GVariant *value)
{
- gpointer orig_value;
+ GVariant *orig_value;
+ g_autoptr(GVariant) new_value = g_variant_ref_sink (value);
gpointer qkey = GUINT_TO_POINTER (g_quark_from_string (key));
+ g_return_if_fail (OSTREE_IS_ASYNC_PROGRESS (self));
+ g_return_if_fail (key != NULL);
+ g_return_if_fail (value != NULL);
+
g_mutex_lock (&self->lock);
if (self->dead)
goto out;
- if (g_hash_table_lookup_extended (hash, qkey, NULL, &orig_value))
+ if (g_hash_table_lookup_extended (self->values, qkey, NULL, (gpointer *) &orig_value))
{
- if (orig_value == value)
+ if (g_variant_equal (orig_value, new_value))
goto out;
}
- g_hash_table_replace (hash, qkey, value);
+ g_hash_table_replace (self->values, qkey, g_steal_pointer (&new_value));
ensure_callback_locked (self);
out:
const char *key,
guint value)
{
- update_key (self, self->uint_values, key, GUINT_TO_POINTER (value));
+ ostree_async_progress_set_variant (self, key, g_variant_new_uint32 (value));
}
void
const char *key,
guint64 value)
{
- gpointer valuep;
-
-#if _OSTREE_HAVE_LP64
- valuep = (gpointer)value;
-#else
- {
- guint64 *boxed = g_malloc (sizeof (guint64));
- *boxed = value;
- valuep = boxed;
- }
-#endif
- update_key (self, self->uint64_values, key, valuep);
+ ostree_async_progress_set_variant (self, key, g_variant_new_uint64 (value));
}
/**